from math import  fsum,  prod
from sys import stderr


def sumprod(*vecs):
    '''矩阵计算积合，也就是计算单列多行矩阵的乘法
    >>> sumprod([10, 20, 30, 40], [2, 4, 6, 8], [1, 2, 3, 4])
    2000
    >>> 10*2*1 + 20*4*2 + 30*6*3 + 40*8*4
    2000
    '''
    return sum(map(prod, zip(*vecs, strict=True)))


def linear_regression(x:list,y:list,forceZero=False):
    '''计算线性回归斜率和截距
    >>> x = [1, 2, 3, 4, 5]
    >>> y = [3 * x[i] for i in range(5)]
    >>> linear_regression(x, y)
    (3.0, 0.0)
    '''


    n = len(x)
    if len(y) != n:
        raise ValueError('linear regression requires that both inputs have same number of data points')
    if n < 2:
        raise ValueError('linear regression requires at least two data points')
    
    if not forceZero:
        xbar = fsum(x) / n
        ybar = fsum(y) / n
        x = [xi - xbar for xi in x]  # List because used three times below
        y = (yi - ybar for yi in y)  # Generator because only used once below
    sxy = sumprod(x, y) + 0.0        # Add zero to coerce result to a float
    sxx = sumprod(x, x)

    try:
        slope = sxy / sxx   # equivalent to:  covariance(x, y) / variance(x)
    except ZeroDivisionError:
        raise ValueError('x is constant')
    intercept = 0.0 if forceZero else ybar - slope * xbar
    return slope, intercept



x = [5000,5000,	5000,	4000,	4000,	4000,	3000,	3000,	3000,	2000,	2000,	2000,	1000,	1000,	1000
]
y = [45747.75333,46387.76833,	46665.6795,	37777.81754,	37884.77921,	37844.64562,	29118.66608,	29310.20358	,29124.04558,	20059.58087,	20004.90537,	20063.90337,	10484.89716,	10428.23516,	10387.498
]

print( linear_regression(x,y,forceZero=True))